#ifndef _STORM_WDM_H_
#define _STORM_WDM_H_


/* Disable warnings about unitialized variables: */
#pragma warning(disable:4700)

/* Disable warnings about unreferenced formal parameters: */
#pragma warning(disable:4100)


// Interlocked operations
#ifdef InterlockedIncrement
#undef InterlockedIncrement
#endif
#define InterlockedIncrement storm_InterlockedIncrement
LONG
storm_InterlockedIncrement(
  IN LONG *Addend
  );

#ifdef InterlockedDecrement
#undef InterlockedDecrement
#endif
#define InterlockedDecrement storm_InterlockedDecrement
LONG
storm_InterlockedDecrement(
  IN LONG *Addend
  );

#ifdef InterlockedCompareExchange
#undef InterlockedCompareExchange
#endif
#define InterlockedCompareExchange storm_InterlockedCompareExchange
LONG
storm_InterlockedCompareExchange(
  __inout LONG volatile *Destination,
  __in LONG ExChange,
  __in LONG Comperand
  );

#ifdef ExInterlockedRemoveHeadList
#undef ExInterlockedRemoveHeadList
#endif
#define ExInterlockedRemoveHeadList storm_ExInterlockedRemoveHeadList
PLIST_ENTRY
storm_ExInterlockedRemoveHeadList(
  IN PLIST_ENTRY ListHead,
  IN PKSPIN_LOCK Lock
  );

#ifdef ExInterlockedInsertHeadList
#undef ExInterlockedInsertHeadList
#endif
#define ExInterlockedInsertHeadList storm_ExInterlockedInsertHeadList
PLIST_ENTRY
storm_ExInterlockedInsertHeadList(
  IN PLIST_ENTRY ListHead,
  IN PLIST_ENTRY ListEntry,
  IN PKSPIN_LOCK Lock
  );

#ifdef ExInterlockedInsertTailList
#undef ExInterlockedInsertTailList
#endif
#define ExInterlockedInsertTailList storm_ExInterlockedInsertTailList
PLIST_ENTRY
storm_ExInterlockedInsertTailList(
  IN PLIST_ENTRY ListHead,
  IN PLIST_ENTRY ListEntry,
  IN PKSPIN_LOCK Lock
  );


// Spinlocks
#ifdef KeInitializeSpinLock
#undef KeInitializeSpinLock
#endif
#define KeInitializeSpinLock storm_KeInitializeSpinLock
VOID
storm_KeInitializeSpinLock(
  IN PKSPIN_LOCK SpinLock
  );

#ifdef KeAcquireSpinLock
#undef KeAcquireSpinLock
#endif
#define KeAcquireSpinLock storm_KeAcquireSpinLock
VOID
storm_KeAcquireSpinLock(
  IN PKSPIN_LOCK SpinLock,
  OUT PKIRQL OldIrql
  );

#ifdef KeReleaseSpinLock
#undef KeReleaseSpinLock
#endif
#define KeReleaseSpinLock storm_KeReleaseSpinLock
VOID
storm_KeReleaseSpinLock(
  IN PKSPIN_LOCK SpinLock,
  IN KIRQL NewIrql
  );

#ifdef KeAcquireSpinLockAtDpcLevel
#undef KeAcquireSpinLockAtDpcLevel
#endif
#define KeAcquireSpinLockAtDpcLevel storm_KeAcquireSpinLockAtDpcLevel
VOID
storm_KeAcquireSpinLockAtDpcLevel(
  IN PKSPIN_LOCK SpinLock
  );

#ifdef KeReleaseSpinLockFromDpcLevel
#undef KeReleaseSpinLockFromDpcLevel
#endif
#define KeReleaseSpinLockFromDpcLevel storm_KeReleaseSpinLockFromDpcLevel
VOID
storm_KeReleaseSpinLockFromDpcLevel(
  IN PKSPIN_LOCK SpinLock
  );

#define IoAcquireCancelSpinLock storm_IoAcquireCancelSpinLock
VOID
storm_IoAcquireCancelSpinLock(
  __out PKIRQL Irql
  );

#define IoReleaseCancelSpinLock storm_IoReleaseCancelSpinLock
VOID
storm_IoReleaseCancelSpinLock(
  __in KIRQL Irql
  );

#ifdef IoAcquireRemoveLock
#undef IoAcquireRemoveLock
#endif
#define IoAcquireRemoveLock storm_IoAcquireRemoveLock
NTSTATUS
storm_IoAcquireRemoveLock(
  IN PIO_REMOVE_LOCK RemoveLock,
  IN OPTIONAL PVOID Tag
  );


// Events, semaphores
#define KeInitializeEvent storm_KeInitializeEvent
VOID
storm_KeInitializeEvent(
  IN PRKEVENT Event,
  IN EVENT_TYPE Type,
  IN BOOLEAN State
  );

#define KeSetEvent storm_KeSetEvent
LONG
storm_KeSetEvent(
  IN PRKEVENT Event,
  IN KPRIORITY Increment,
  IN BOOLEAN Wait
  );

#define KeResetEvent storm_KeResetEvent
LONG
storm_KeResetEvent(
  IN PRKEVENT Event
  );

#define KeClearEvent storm_KeClearEvent
VOID
storm_KeClearEvent(
  IN PRKEVENT Event
  );

#define KeInitializeSemaphore storm_KeInitializeSemaphore
VOID
storm_KeInitializeSemaphore(
  IN PRKSEMAPHORE Semaphore,
  IN LONG Count,
  IN LONG Limit
  );

#define KeReleaseSemaphore storm_KeReleaseSemaphore
LONG
storm_KeReleaseSemaphore(
  IN PRKSEMAPHORE Semaphore,
  IN KPRIORITY Increment,
  IN LONG Adjustment,
  IN BOOLEAN Wait
  );

#define KeWaitForSingleObject storm_KeWaitForSingleObject
NTSTATUS
storm_KeWaitForSingleObject(
  IN PVOID Object,
  IN KWAIT_REASON WaitReason,
  IN KPROCESSOR_MODE WaitMode,
  IN BOOLEAN Alertable,
  IN PLARGE_INTEGER Timeout OPTIONAL
  );


// Device operations
#define IoCreateDevice storm_IoCreateDevice
NTSTATUS
storm_IoCreateDevice(
  IN PDRIVER_OBJECT DriverObject,
  IN ULONG DeviceExtensionSize,
  IN PUNICODE_STRING DeviceName OPTIONAL,
  IN DEVICE_TYPE DeviceType,
  IN ULONG DeviceCharacteristics,
  IN BOOLEAN Exclusive,
  OUT PDEVICE_OBJECT *DeviceObject
  );

#define IoAttachDeviceToDeviceStack storm_IoAttachDeviceToDeviceStack
PDEVICE_OBJECT
storm_IoAttachDeviceToDeviceStack(
  IN PDEVICE_OBJECT SourceDevice,
  IN PDEVICE_OBJECT TargetDevice
  );


// IRP operations
#define IoAllocateIrp storm_IoAllocateIrp
PIRP
storm_IoAllocateIrp(
  IN CCHAR StackSize,
  IN BOOLEAN ChargeQuota
  );

#define IoBuildDeviceIoControlRequest storm_IoBuildDeviceIoControlRequest
PIRP
storm_IoBuildDeviceIoControlRequest(
  IN ULONG IoControlCode,
  IN PDEVICE_OBJECT DeviceObject,
  IN PVOID InputBuffer OPTIONAL,
  IN ULONG InputBufferLength,
  OUT PVOID OutputBuffer OPTIONAL,
  IN ULONG OutputBufferLength,
  IN BOOLEAN InternalDeviceIoControl,
  IN PKEVENT Event,
  OUT PIO_STATUS_BLOCK IoStatusBlock
  );

#define IoFreeIrp storm_IoFreeIrp
VOID
storm_IoFreeIrp(
  IN PIRP pirp
  );

#ifdef IoCompleteRequest
#undef IoCompleteRequest
#endif
#define IoCompleteRequest storm_IoCompleteRequest
VOID
storm_IoCompleteRequest(
  IN PIRP pirp,
  IN CCHAR PriorityBoost
  );

#define IoCancelIrp storm_IoCancelIrp
BOOLEAN
storm_IoCancelIrp(
  IN PIRP Irp
  );

#define IoMarkIrpPending storm_IoMarkIrpPending
VOID
storm_IoMarkIrpPending(
  IN OUT PIRP pirp
  );


// Setting cancel and complete routines
#ifdef IoSetCancelRoutine
#undef IoSetCancelRoutine
#endif
#define IoSetCancelRoutine storm_IoSetCancelRoutine
PDRIVER_CANCEL
storm_IoSetCancelRoutine(
  IN PIRP pirp,
  IN PDRIVER_CANCEL CancelRoutine
  );

#define IoSetCompletionRoutine storm_IoSetCompletionRoutine
VOID
storm_IoSetCompletionRoutine(
  IN PIRP pirp,
  IN PIO_COMPLETION_ROUTINE CompletionRoutine,
  IN PVOID Context,
  IN BOOLEAN InvokeOnSuccess,
  IN BOOLEAN InvokeOnError,
  IN BOOLEAN InvokeOnCancel
  );

#define IoSetCompletionRoutineEx storm_IoSetCompletionRoutineEx
NTSTATUS
storm_IoSetCompletionRoutineEx(
  IN PDEVICE_OBJECT DeviceObject,
  IN PIRP Irp,
  IN PIO_COMPLETION_ROUTINE CompletionRoutine,
  IN PVOID Context,
  IN BOOLEAN InvokeOnSuccess,
  IN BOOLEAN InvokeOnError,
  IN BOOLEAN InvokeOnCancel
  );

void CallCompletionRoutine(PIRP Irp);

#ifdef IoCallDriver
#undef IoCallDriver
#endif
#define IoCallDriver storm_IoCallDriver
NTSTATUS
storm_IoCallDriver(
  IN PDEVICE_OBJECT DeviceObject,
  IN OUT PIRP Irp
  );

#ifdef PoCallDriver
#undef PoCallDriver
#endif
#define PoCallDriver storm_PoCallDriver
NTSTATUS
storm_PoCallDriver(
  IN PDEVICE_OBJECT DeviceObject,
  IN OUT PIRP Irp
  );


// Utils
#define ExAllocatePoolWithTag storm_ExAllocatePoolWithTag
PVOID
storm_ExAllocatePoolWithTag(
  IN POOL_TYPE PoolType,
  IN SIZE_T NumberOfBytes,
  IN ULONG Tag
  );

#endif

